import axios from 'axios'
import router from '@/router'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'

// 标识是否正在刷新Token，避免重复刷新
let isRefreshing = false;
// 请求队列，用于存放在Token刷新过程中等待的请求
let requestsQueue = [];

// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // request timeout
})

// request interceptor
service.interceptors.request.use(
  config => {
    // do something before request is sent

    if (store.getters.token) {
      // let each request carry token
      // ['X-Token'] is a custom headers key
      // please modify it according to the actual situation
      // config.headers['X-Token'] = getToken()
      config.headers['Authorization'] = "Bearer " + getToken()
    }
    return config
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)

// response interceptor
service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
  */

  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  response => {
    const res = response.data
    
    // 服务器响应成功的操作
    if (response.status == 204) {
      return response

    }
    return res

    // if the custom code is not 20000, it is judged as an error.
    // if (res.code !== 20000) {
    //   Message({
    //     message: res.message || 'Error',
    //     type: 'error',
    //     duration: 5 * 1000
    //   })

    //   // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
    //   if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
    //     // to re-login
    //     MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
    //       confirmButtonText: 'Re-Login',
    //       cancelButtonText: 'Cancel',
    //       type: 'warning'
    //     }).then(() => {
    //       store.dispatch('user/resetToken').then(() => {
    //         location.reload()
    //       })
    //     })
    //   }
    //   return Promise.reject(new Error(res.message || 'Error'))
    // } else {
    //   return res
    // }
  },
  async error => {
    // console.log('err' + error) // for debug
    // Message({
    //   message: error.message,
    //   type: 'error',
    //   duration: 5 * 1000
    // })

    const {response} = error; // 获取错误响应对象
    const originalRequest = error.config; // 保存原始请求配置
    if (response && response.status === 401) {

      if (error.response.data.msg == "令牌无效或已过期") {

        await store.dispatch('user/resetToken')
        
        // router.push('/login?redirect=' + router.currentRoute.path);
        return Promise.reject(error);
      }

      const refreshToken = getToken('refresh');
      if (!refreshToken) {
        router.push('/login?redirect=' + router.currentRoute.path);
      }

      if (!isRefreshing) {
        isRefreshing = true;

        try {

          // 发送携带RefreshToken的请求来获取新的Token
          const refreshResponse = await store.dispatch('user/refreshToken')

          // 获取新Token并存储
          const newAuthToken = refreshResponse.access;

          // 执行所有挂起的请求
          requestsQueue.forEach(cb => cb(newAuthToken));
          requestsQueue = [];

          // 更新原始请求的AuthToken头并重新发送请求
          response.headers['Authorization'] = "Bearer " + newAuthToken
          // 如果设置了代理跨域这里需要重置，不然的话会多一个/api
          // originalRequest.baseURL = '/'

          // 重新提交
          // return service.request(originalRequest)
          return service(originalRequest)

        } catch (refreshError) {
          await store.dispatch('user/resetToken')
          return Promise.reject(refreshError);

        } finally {
          isRefreshing = false;
        }
      } else {
        // 如果Token正在刷新，将请求加入队列，并在Token刷新完成后重新发送请求
        return new Promise(resolve => {
          requestsQueue.push((newToken) => {
            // originalRequest.headers['AuthToken'] = newToken;
            originalRequest.headers['Authorization'] = "Bearer " + newToken
            resolve(service(originalRequest));
          });
        });
      }
      
    }else if(response && response.status === 400){
      Message({
        message: response.data.msg || 'Error',
        type: 'error',
        duration: 5 * 1000
      })
      return error;
      
    }else{
      Message({
        message: response.data.msg || 'Error',
        type: 'error',
        duration: 5 * 1000
      })
    }

    return Promise.reject(error)
  }
)

export default service
